package com.ruoyi.controller;

import java.util.List;
import java.util.Map;
import java.util.function.Function;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.Size;

import com.ruoyi.common.enums.OrderNodeEnums;
import com.ruoyi.order.service.IMgOrderNodeRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.common.util.ListConvertMap;
import com.common.util.MergeDataSource;
import com.param.concat.IPage;
import com.param.impl.GetUserDataByIdRequestParam;
import com.ruoyi.center.domain.NoticeCenter;
import com.ruoyi.center.service.INoticeCenterService;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.config.manager.service.IServicePriceConfService;
import com.ruoyi.manager.domain.MgServiceManager;
import com.ruoyi.manager.service.IMgServiceManagerService;
import com.ruoyi.order.domain.Manuscript;
import com.ruoyi.order.domain.MgOrder;
import com.ruoyi.order.domain.MgOrderAssign;
import com.ruoyi.order.domain.OrderLog;
import com.ruoyi.order.service.IManuscriptService;
import com.ruoyi.order.service.IMgOrderAssignService;
import com.ruoyi.order.service.IMgOrderService;
import com.ruoyi.order.service.IOrderLogService;
import com.ruoyi.oss.config.OssConfig;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.user.service.IMgUserService;

/**
 * 订单Controller
 *
 * @author ruoyi
 * @date 2023-12-24
 */
@RestController
@RequestMapping("/orderEdit")
public class OrderByEditController extends BaseController {
	@Autowired
	private IMgOrderService mgOrderService;

	private IManuscriptService manuscriptService;

	IMgUserService mgUserService;

	IServicePriceConfService priceConfService;

	OssConfig ossConfig;

	IOrderLogService orderLogService;
	
	INoticeCenterService centerService;
	
	IMgServiceManagerService serviceManager;

	ISysUserService sysUserService;
	
	IMgOrderAssignService orderAssignService;
	
	@Resource
    public void setOrderAssignService(IMgOrderAssignService orderAssignService) {
        this.orderAssignService = orderAssignService;
    }
	

	@Resource
	private IMgOrderNodeRecordService iMgOrderNodeRecordService;

	
	
	@Resource
	public void setSysUserService(ISysUserService sysUserService) {
		this.sysUserService = sysUserService;
	}
	

	@Resource
	public void setServiceManager(IMgServiceManagerService serviceManager) {
		this.serviceManager = serviceManager;
	}

	@Resource
	public void setCenterService(INoticeCenterService centerService) {
		this.centerService = centerService;
	}

	@Resource
	public void setOrderLogService(IOrderLogService orderLogService) {
		this.orderLogService = orderLogService;
	}

	@Resource
	public void setOssConfig(OssConfig ossConfig) {
		this.ossConfig = ossConfig;
	}

	@Resource
	public void setPriceConfService(IServicePriceConfService priceConfService) {
		this.priceConfService = priceConfService;
	}

	@Resource
	public void setMgUserService(IMgUserService mgUserService) {
		this.mgUserService = mgUserService;
	}


	 /**
     * 封装分页对象
     */
    public PageDomain getPageDomainByPost(IPage page)
    {
        PageDomain pageDomain = new PageDomain();
        pageDomain.setPageNum(page.getPageNum());
        pageDomain.setPageSize(page.getPageSize());
        pageDomain.setReasonable(true);
        return pageDomain;
    }


	/**
	 * 订单列表
	 */
	@PreAuthorize("@ss.hasPermi('edit:order:list')")
	@GetMapping("/list")
	public TableDataInfo list(MgOrderAssign mgOrder) {
		startPage();
		
		mgOrder.setProcessed(getUserId());
		
		List<MgOrderAssign> list = orderAssignService.selectList(mgOrder);

		parseOrderAssignAfter(list);

		return getDataTable(list);

	}

	/**
	 *         List<MgOrder> list = mgOrderService.selectListByEditQuery(mgOrder);
	 * 订单列表
	 */
//	@PreAuthorize("@ss.hasPermi('order:list')")
	@GetMapping("/listQuery")
	public TableDataInfo listQuery(MgOrderAssign mgOrder) {
		startPage();
		
		mgOrder.setProcessed(getUserId());
		List<MgOrderAssign> list = orderAssignService.selectList(mgOrder);

//		parseOrderAfter(list);

		return getDataTable(list);

	}
	
	/**
	 * 查询 订单列表
	 * @param list
	 */
	private void parseOrderAssignAfter(List<MgOrderAssign> list) {
		int size = list.size();

		if (0 >= size) {
			return ;
		}

		int[] ids = list.stream().filter(e -> null != e.getProcessed()).distinct()
				.mapToInt(e -> e.getOrderId().intValue()).toArray();

		if (0 == ids.length || (1 == ids.length && 0 == ids[0])) {
			return ;
		}

		List<Manuscript> sysUsersByIds = manuscriptService.getManuscriptByOrderIds(ids);

		MergeDataSource<MgOrderAssign> mergeDataSource = new MergeDataSource<MgOrderAssign>(list);

		Map<Integer, List<Manuscript>> listToMap = ListConvertMap.listToMapList(sysUsersByIds, Manuscript::getOrderId);

		Function<MgOrderAssign, Integer> function = (e) -> ((MgOrderAssign)e).getOrderId().intValue();
		
	
		List<MgOrder> orderList = mgOrderService.selectListByIds(ids);
		
		
		Map<Integer, MgOrder> listToMapOrder = ListConvertMap.listToMap(orderList, MgOrder::getId);
		
		mergeDataSource.mergeRelease(function, listToMap, (MgOrderAssign t, List<Manuscript> item) -> {

			t.setManscripts(item);
			return t;
		});
		
		mergeDataSource.mergeRelease(function, listToMapOrder, (MgOrderAssign t, MgOrder order) -> {
			t.setProfessionalField(order.getProfessionalField());	
			return t;
		});
		
		
		
		//  需求描述
		ids = list.stream().filter(e -> {
			byte status = e.getServiceStatus();
			
			return 1 == status || 2 == status;
		} ).distinct().mapToInt(e -> e.getOrderId().intValue()).toArray();
		
		
		List<OrderLog> selectListByIds = orderLogService.selectListByIds(ids);
		
		mergeDataSource.mergeRelease(
				function, ListConvertMap.listToMap(selectListByIds, OrderLog::getOrderId), 
				(MgOrderAssign t, OrderLog item) -> {
					if (0 == t.getServiceStatus().compareTo((byte) 0)) {
						return t;
					}
					t.setRemarks(item.getRequirement());
					return t;
		});
		
	}

	
	

	/**
	 * 查询 订单列表
	 * @param list
	 */
	private void parseOrderAfter(List<MgOrder> list) {
		int size = list.size();

		if (0 >= size) {
			return ;
		}

		int[] ids = list.stream().filter(e -> null != e.getProcessed()).distinct()
				.mapToInt(e -> e.getId()).toArray();

		if (0 == ids.length || (1 == ids.length && 0 == ids[0])) {
			return ;
		}

		List<Manuscript> sysUsersByIds = manuscriptService.getManuscriptByOrderIds(ids);

		MergeDataSource<MgOrder> mergeDataSource = new MergeDataSource<MgOrder>(list);

		Map<Integer, List<Manuscript>> listToMap = ListConvertMap.listToMapList(sysUsersByIds, Manuscript::getOrderId);

		mergeDataSource.mergeRelease(MgOrder::getId, listToMap, (MgOrder t, List<Manuscript> item) -> {

			t.setManscripts(item);
			return t;
		});
		
		//  需求描述
		ids = list.stream().filter(e -> {
			byte status = e.getServiceStatus();
			
			return 1 == status || 2 == status;
		} ).distinct().mapToInt(e -> e.getId()).toArray();
		
		
		List<OrderLog> selectListByIds = orderLogService.selectListByIds(ids);
		
		
		
		mergeDataSource.mergeRelease(
				MgOrder::getId, ListConvertMap.listToMap(selectListByIds, OrderLog::getOrderId), 
				(MgOrder t, OrderLog item) -> {
					
					
					
					t.setRemarks(item.getRequirement());
					return t;
		});
		
	}

	/**
	 * 根据用户id查询余额支付的订单列表
	 */
	@PreAuthorize("@ss.hasPermi('recharge:use:record')")
	@GetMapping("/listRechargeByUser")
	public TableDataInfo listByUser(@Validated GetUserDataByIdRequestParam dataByIdRequestParam) {
		startPage();

		return getDataTable(this.mgOrderService.selectListByRecharge(dataByIdRequestParam));
	}

	/**
	 * 根据用户id查询订单列表
	 */
	@PreAuthorize("@ss.hasPermi('user:order:single')")
	@GetMapping("/listByUser")
	public TableDataInfo listRechargeByUser(@Validated GetUserDataByIdRequestParam dataByIdRequestParam) {
		startPage();

		return getDataTable(this.mgOrderService.selectList(dataByIdRequestParam));
	}

	/**
	 * 导出订单列表
	 */
	@PreAuthorize("@ss.hasPermi('order:order:export')")
	@Log(title = "订单", businessType = BusinessType.EXPORT)
	@PostMapping("/export")
	public void export(HttpServletResponse response, MgOrder mgOrder) {
		List<MgOrder> list = mgOrderService.selectList(mgOrder);
		ExcelUtil<MgOrder> util = new ExcelUtil<MgOrder>(MgOrder.class);
		util.exportExcel(response, list, "订单数据");
	}

	/**
	 * 获取订单详细信息
	 */
	@PreAuthorize("@ss.hasPermi('order:order:query')")
	@GetMapping(value = "/{id}")
	public AjaxResult getInfo(@PathVariable("id") Integer id) {
		return success(mgOrderService.selectById(id));
	}


//	@PreAuthorize("@ss.hasPermi('order:order:query')")
//	@PutMapping(value = "parseByStart/{id}")
//	@Transactional
//	public AjaxResult parseByStart(@PathVariable("id") Integer id) {
//
//		MgOrder data = mgOrderService.selectById(id);
//
//		if (null == data) {
//			return error("订单不存在");
//		}
//
//		mgOrderService.startParse(id);
//		
//		Long userId = this.getUserId();
//		
//		Integer orderAssignsMaxIdForUpdate = orderAssignService.getOrderAssignsMaxIdForUpdate(id, userId);
//		
//		MgOrderAssign assign = new MgOrderAssign();
//		
//		assign.setId(orderAssignsMaxIdForUpdate.longValue());
//		
//		assign.setParseTime(System.currentTimeMillis() / 1000);
//		
//		orderAssignService.update(assign);
//		
//		if (0 != data.getServiceStatus()) {
//			orderLogService.insertLog(id, data.getUserId().intValue(), 4, data.getPayManagerId(), 2);
//		}
//
//		
//		// 发送通知
//		NoticeCenter notification = noticeAdmin(id, data, 1,"处理订单", "您好", "进入处理中，请时刻关注订单状态。");
//		
//		centerService.insert(notification);
//		
//		return AjaxResult.success(1);
//
//	}

	@PutMapping(value = "parseByStart/{id}")
	@Transactional
	public AjaxResult parseByStart(@PathVariable("id") Integer id) {

		MgOrderAssign data = orderAssignService.selectById(id);

		if (null == data) {
			return error("处理人订单不存在");
		}

		mgOrderService.startParse(data.getOrderId().intValue());
		
//		Long userId = this.getUserId();
		
//		Integer orderAssignsMaxIdForUpdate = orderAssignService.getOrderAssignsMaxIdForUpdate(id, userId);
		
		MgOrderAssign assign = new MgOrderAssign();
		
		assign.setId(id.longValue());
		
		assign.setOrderStatus(4);
		assign.setEditStatus((byte) 1);
		
		
		assign.setParseTime(System.currentTimeMillis() / 1000);
		
		orderAssignService.update(assign);
		
		if (0 != data.getServiceStatus()) {
			orderLogService.insertLog(id, data.getUserId().intValue(), 4, data.getPayManagerId(), 2);
		}
		
		// 发送通知
		NoticeCenter notification = noticeAdmin(data.getOrderId().intValue(), data, 0,"处理订单", "您好", "进入处理中，请时刻关注订单状态。");
		
		centerService.insert(notification);
		
		return AjaxResult.success(1);

	}
	
	protected NoticeCenter noticeAdmin(Integer id, MgOrderAssign data, int platform, String title, String prefix, String suffix) {
		NoticeCenter notification = new NoticeCenter();
		
		// 填充对象
		notification.setUserId(data.getUserId().intValue());
		
		List<MgServiceManager> selectMgServiceManagerList = serviceManager.selectMgServiceManagerList(new MgServiceManager());
		
		Map<Integer, MgServiceManager> listToMap = ListConvertMap.listToMap(selectMgServiceManagerList, MgServiceManager::getId);
		
		MgServiceManager mgServiceManager = listToMap.get(data.getServiceId());

		// 
		String content = prefix + "【"+ mgServiceManager.getTypeName() +"】订单"+ data.getOrderSn() + suffix;
		
		notification.setNoticeContent(content);
		
		notification.setNoticeType(0);
		
		notification.setUserId(data.getUserId().intValue());
		
		notification.setTypeId(id);
		
		notification.setPlatform(platform);
		
		notification.setTitle(title);
		return notification;
	}

	/**
	 * 完工确认
	 * @param id
	 * @param manuscripts
	 * @return
	 */
	@PutMapping(value = "uploadManuscripts/{id}")
	@Transactional
	public AjaxResult uploadManuscripts(@PathVariable("id") Integer id,  
			@RequestBody List<Manuscript> manuscripts) {

		if (null == manuscripts || 0 == manuscripts.size()) {
			return error("请上传附件");
		}
		
		MgOrderAssign data = orderAssignService.selectById(id);

		if (null == data) {
			return error("订单不存在");
		}

		String url = ossConfig.getURL();

		long timeMillis = System.currentTimeMillis() / 1000;

		for (Manuscript manuscript : manuscripts) {

			manuscript.setUserId(data.getUserId().intValue());

			manuscript.setOrderId(data.getOrderId().intValue());

			manuscript.setOrderLogId(0);

			manuscript.setStatus(0);

			manuscript.setPayManagerId(data.getPayManagerId());

			manuscript.setEditUserId(getUserId().intValue());

			manuscript.setFile(
				manuscript
				.getFile()
				.replace("https://", "")
				.replace("http://", "")
				.replace(url, "")
			);

			manuscript.setCreateTime(timeMillis);

            manuscript.setUpdateTime(timeMillis);
		}

		
		
		manuscriptService.batchInsert(manuscripts, id);

		orderAssignService.complateOrder(id);
		
		mgOrderService.completeParse(data.getOrderId().intValue());

		orderLogService.insertLog(id, data.getUserId().intValue(), 5, data.getPayManagerId(), 1);
		
		// 编辑名(ID:01234567)完成【服务名称】订单ZF202xxxxxxxxxXX的编辑工作，请及时处理!

		SysUser selectUserById = sysUserService.selectUserById(data.getProcessed());
		
		NoticeCenter notification = noticeAdmin(data.getOrderId().intValue(), data, 1, "编辑完工确认通知", selectUserById.getNickName()+ "(ID:" + selectUserById.getUserId()+")完成", "请及时处理！");
		
		centerService.insert(notification);
		return AjaxResult.success(1);

	}
	
//	/**
//	 * 完工确认
//	 * @param id
//	 * @param manuscripts
//	 * @return
//	 */
//	@PutMapping(value = "uploadManuscripts/{id}")
//	@Transactional
//	public AjaxResult uploadManuscripts(@PathVariable("id") Integer id,  
//			@RequestBody List<Manuscript> manuscripts) {
//
//		if (null == manuscripts || 0 == manuscripts.size()) {
//			return error("请上传附件");
//		}
//		
//		MgOrder data = mgOrderService.selectById(id);
//
//		if (null == data) {
//			return error("订单不存在");
//		}
//
//		String url = ossConfig.getURL();
//
//		long timeMillis = System.currentTimeMillis() / 1000;
//
//		for (Manuscript manuscript : manuscripts) {
//
//			manuscript.setUserId(data.getUserId().intValue());
//
//			manuscript.setOrderId(data.getId());
//
//			manuscript.setOrderLogId(0);
//
//			manuscript.setStatus(0);
//
//			manuscript.setPayManagerId(data.getPayManagerId());
//
//			manuscript.setEditUserId(getUserId().intValue());
//
//			manuscript.setFile(
//				manuscript
//				.getFile()
//				.replace("https://", "")
//				.replace("http://", "")
//				.replace(url, "")
//			);
//
//			manuscript.setCreateTime(timeMillis);
//
//            manuscript.setUpdateTime(timeMillis);
//		}
//
//		manuscriptService.batchInsert(manuscripts, id);
//
//		mgOrderService.completeParse(id);
//
//		orderLogService.insertLog(id, data.getUserId().intValue(), 5, data.getPayManagerId(), 1);
//		
//		// 编辑名(ID:01234567)完成【服务名称】订单ZF202xxxxxxxxxXX的编辑工作，请及时处理!
//
//		SysUser selectUserById = sysUserService.selectUserById(data.getProcessed());
//		
//		NoticeCenter notification = noticeAdmin(id, data, 1, "编辑完工确认通知", selectUserById.getNickName()+ "(ID:" + selectUserById.getUserId()+")完成", "请及时处理！");
//		
//		centerService.insert(notification);
//		return AjaxResult.success(1);
//
//	}



	/**
	 * 新增订单
	 */
	@PreAuthorize("@ss.hasPermi('order:order:add')")
	@Log(title = "订单", businessType = BusinessType.INSERT)
	@PostMapping
	public AjaxResult add(@RequestBody MgOrder mgOrder) {
		return toAjax(mgOrderService.insert(mgOrder));
	}

	/**
	 * 修改订单
	 */
	@PreAuthorize("@ss.hasPermi('order:order:edit')")
	@Log(title = "订单", businessType = BusinessType.UPDATE)
	@PutMapping
	public AjaxResult edit(@RequestBody MgOrder mgOrder) {
		return toAjax(mgOrderService.update(mgOrder));
	}



	@Resource
	public void setManuscriptService(IManuscriptService manuscriptService) {
		this.manuscriptService = manuscriptService;
	}
}
